import { computed, reactive, ref, unref } from 'vue'
import { useWebSocket as $useWebSocket, type UseWebSocketReturn } from '@vueuse/core'
// import { getToken } from '/@/utils/auth';

const state = reactive({
  server: '',
  sendValue: '',
  recordList: [] as { id: number; time: number; res: string }[]
})

const result = ref<UseWebSocketReturn<any>>()

const listeners = new Map()

/**
 * 开启 WebSocket 链接，全局只需执行一次
 * @param url
 */
export function connectWebSocket(url: string) {
  try {
    if (!unref(getIsOpen)) {
      state.server = url
      // const accessToken = (getToken() || '') as string;
      // const token = accessToken.replace('bearer ', '');
      const token = ''
      console.log('connectWebSocket token.....', token)
      result.value = $useWebSocket(state.server, {
        // 自动重连
        autoReconnect: {
          retries: 3,
          delay: 1000,
          onFailed() {
            console.error('Failed to connect WebSocket after 3 retries')
          }
        },
        // 心跳检测
        heartbeat: {
          message: 'ping',
          interval: 1000
        },
        transports: ['websocket']
        // protocols: [token],
      })

      //result.value.open();
      const ws = unref(result.value.ws)
      if (ws) {
        ws.onopen = onOpen
        ws.onclose = onClose
        ws.onerror = onError
        ws.onmessage = onMessage
      }
    }
  } catch (error) {
    console.error('connectWebSocket error.....', error)
  }
}

function onOpen() {
  console.log('[WebSocket] onOpen')
  for (const callback of listeners.keys()) {
    try {
      callback({ code: 0 })
    } catch (err) {}
  }
}

function onClose(e: CloseEvent) {
  console.log('[WebSocket] onClose: ', e)
  for (const callback of listeners.keys()) {
    try {
      callback({ code: -1, error: e })
    } catch (err) {}
  }
}

function onError(e: Event) {
  console.log('[WebSocket] onError: ', e)
  for (const callback of listeners.keys()) {
    try {
      callback({ code: -9, error: e })
    } catch (err) {}
  }
}

let oldData = ''
function onMessage(e: MessageEvent) {
  if (e.data == oldData) return
  oldData = e.data
  if (e.data === 'ping') {
    return
  }
  try {
    // const data = JSON.parse(e.data);
    for (const callback of listeners.keys()) {
      try {
        callback({ code: 0, data: e.data })
      } catch (err) {
        console.error(err)
      }
    }
  } catch (err) {
    console.error('[WebSocket] data parse failed:', err)
  }
}

export function sendWsData(data: string) {
  console.log('sendWsData', data, result.value)
  result.value?.send(data)
}
/**
 * 判断 WebSocket 是否是开启状态
 */
export const getIsOpen = computed(() => result.value?.status.value === 'OPEN')

/**
 * 添加 WebSocket 消息监听
 * @param callback
 */
export function addWsListener(callback: (data: object) => any) {
  if (!listeners.has(callback)) {
    if (typeof callback === 'function') {
      listeners.set(callback, null)
    } else {
      console.debug('[WebSocket] 添加 WebSocket 消息监听失败：传入的参数不是一个方法')
    }
  }
}

/**
 * 解除 WebSocket 消息监听
 *
 * @param callback
 */
export function removeWsListener(callback: (data: object) => any) {
  listeners.delete(callback)
}

export function useWebSocket() {
  return unref(result)
}
